(function () {
    z._icons = z.cdn_url('img/icon/richtext_icons.gif');
    z._rts = {
        group1 : {
            bold: {
                icon_pos:   '0 0',
                cmd:        'bold',
                label:      'Bold Ctrl + B',
                type:       'bt'
            },
            italic: {
                cmd:    'italic',
                type: 'bt',
                label: 'Italic Ctrl + I',
                icon_pos: '-60px 0'
            },
            underline: {
                cmd:        'underline',
                type:       'bt',
                label:      'Underline Ctrl + U',
                icon_pos:   '-140px 0'
            },
            strikethrough: {
                cmd:        'strikethrough',
                type:       'bt',
                label:      'Strikethrough Ctrl + T',
                icon_pos:   '-120px 0'
            }
        },
        group2 : {
            justifyleft: {
                cmd: 'justifyleft',
                type: 'bt',
                label: 'Justify Left',
                icon_pos: '-460px 0'
            },
            justifyright: {
                cmd: 'justifyright',
                type: 'bt',
                label: 'Justify Right',
                icon_pos: '-480px 0'
            },
            justifycenter: {
                cmd: 'justifycenter',
                type: 'bt',
                label: 'Justify Center',
                icon_pos: '-420px 0'
            },
            justifyfull: {
                cmd: 'justifyfull',
                type: 'bt',
                label: 'Justify Full',
                icon_pos: '-440px 0'
            },
            indent: {
                cmd: 'indent',
                type: 'bt',
                label: 'Indent',
                icon_pos: '-400px 0'
            },
            outdent: {
                cmd: 'outdent',
                type: 'bt',
                label: 'Outdent',
                icon_pos: '-540px 0'
            },
            insertunorderedlist: {
                cmd: 'insertunorderedlist',
                type: 'bt',
                label: 'Insert Unordered List',
                icon_pos: '-20px 0'
            },
            insertorderedlist: {
                cmd: 'insertorderedlist',
                type: 'bt',
                label: 'Insert Unordered List',
                icon_pos: '-80px 0'
            }
        },
        group3 : {
            undo: {
                cmd: 'undo',
                type: 'bt',
                label: 'Undo',
                icon_pos: '-160px 0'
            },
            redo: {
                cmd: 'redo',
                type: 'bt',
                label: 'Redo',
                icon_pos: '-100px 0'
            }
        },
        group4: {
            createlink: {
                cmd: 'createlink',
                type: 'bt',
                label: 'Create Link',
                icon_pos: '-500px 0',
                callback: function (opts) {
                    //y += 20;
                    this.show_link_manager(opts.offsetLeft, opts.offsetTop + 20);
                }
            },
            unlink: {
                cmd: 'unlink',
                type: 'bt',
                label: 'unlink',
                icon_pos: '-640px 0'
            },
            insertimage: {
                cmd: 'insertimage',
                type: 'bt',
                label: 'Insert Image',
                icon_pos: '-380px 0',
                callback: function (opts) {
                    if ( ! cdn)
                        cdn = new z.cdn();
                    var othis = this;
                    cdn.show(null, function () {
                        //alert(this.img_cdn_path);
                        //thumbnail_img.src = z.cdn_url(this.img_cdn_path);
                        othis.exec('insertimage', 
                               {
                                src: z.cdn_url(this.img_cdn_path), 
                                align: this.select_align.value,
                                width: this.input_width.value,
                                height: this.input_height.value
                               });
                        //othis.exec('inserthtml', '<img src="' + z.cdn_url(this.img_cdn_path)) + '" />';
                        this.hide();
                    });
                    cdn.set_pos(0, opts.mouse_pos.y);
                }
            },
            showhtml: {
                cmd: 'showhtml',
                type: 'bt',
                label: 'Show Html',
                icon_pos: '-260px 0',
                callback: function () {
                    //var elem = this.elem;
                    var doc = this.doc;
                    //var iframe = this.iframe;
                    if ( ! doc.is_text) {
                        /*elem.style.display = 'block';
                        iframe.style.display = 'none';
                        elem.value = doc.body.innerHTML.toString();*/
                        if (document.all) {
                            doc.body.innerText = doc.body.innerHTML;
                        } else {
                            var htmlSrc = doc.createTextNode(doc.body.innerHTML);
                            doc.body.innerHTML = "";
                            doc.body.appendChild(htmlSrc);
                        }
                        doc.is_text = true;
                    } else {
                        
                        if (document.all) {
                            var output = escape(doc.body.innerText);
                            output = output.replace("%3CP%3E%0D%0A%3CHR%3E", "%3CHR%3E");
                            output = output.replace("%3CHR%3E%0D%0A%3C/P%3E", "%3CHR%3E");
                            
                            doc.body.innerHTML = unescape(output);
                        } else {
                            var htmlSrc = doc.body.ownerDocument.createRange();
                            htmlSrc.selectNodeContents(doc.body);
                            doc.body.innerHTML = htmlSrc.toString();
                        }
                        doc.is_text = false;
                    }
                }
            }
        }
        /*group5 : {
            fontsize: {
                cmd: 'fontsize',
                type: 'select',
                label: 'Font Size',
                create_icon: function () {
                    var select = document.createElement('select');
                    for (var size = 1; size < 8; size++) {
                        var option = document.createElement('option');
                        select.appendChild(option);
                        
                        option.value = size;
                        option.innerHTML = size;
                        if (size == 1) {
                            option.selected = 'selected';
                        }
                    }
                    return select;
                }
            },
            formatblock: {
                cmd: 'formatblock',
                type: 'select',
                label: 'Format Block',
                create_icon: function () {
                    var select = document.createElement('select');
                    var p = document.createElement('option');
                    p.innerHTML = 'Paragraph';
                    p.value = '<p>';
                    select.appendChild(p);
                    for (var level = 1; level <= 6; level++ ){
                        var h = document.createElement('option');
                        h.innerHTML = 'H' + level;
                        h.value = '<h' + level + '>';
                        select.appendChild(h);
                    }
                    return select;
                }
            }
        }*/
    };
    z.richtext = function (opts) {
        var othis = this;
        if ( ! opts.elem) {
            alert('create rich text failed');
            return;
        }
        this.elem = z.s(opts.elem);
        
        var wrap = document.createElement('div');
        this.wrap = wrap;
        this.elem.parentNode.insertBefore(wrap, this.elem);
        wrap.className = 'richtext';
        
        var head = document.createElement('div');
        this.head = head;
        wrap.appendChild(head);
        head.className = 'richtext_head';
        
        var body = document.createElement('div');
        this.body = body;
        wrap.appendChild(body);
        body.className = 'richtext_body';
        
        var iframe = document.createElement('iframe');
        this.iframe = iframe;
        body.appendChild(iframe);
        
        var icons_img = new Image();
        icons_img.src = z._icons;
        
        this.icons_src = z._icons;
        
        
        if (icons_img.complete) {
            this._setup_head();
        } else {
            icons_img.onload = function () {
                othis._setup_head();
            };
        }
        
        
        this._setup_iframe();
        this.doc = this.get_doc();
        this.elem.style.display = 'none';
    };
    z.richtext.prototype = {
        exec: function (cmd, opt) {
            var doc = this.doc;
            var iframe = this.iframe;
            iframe.contentWindow.focus();
            if (cmd == 'insertimage') {
                this.insertimage(opt);
            } else {
                doc.execCommand(cmd, false, opt);
            }
            iframe.contentWindow.focus();
        },
        insertimage: function (opt) {
            var doc = this.doc;
            var img = doc.createElement('img');
            img.src = opt.src;
            var align = opt.align;
            if (align == 'left') {
                img.setAttribute('style', "float: left");
            } else if (align == 'right'){
                img.setAttribute('style', "float: right");
            } else if (align == 'middle') {
                img.setAttribute('style', "vertical-align: middle;");
            }
            if (opt.width) {
                img.setAttribute('width', opt.width);
            }
            if (opt.height) {
                img.setAttribute('height', opt.height);
            }
            this.insertnode(img);
            
            
        },
        insertnode: function (node) {
            var doc = this.doc;
            var sel = this.get_sel();
            if (z.isIE) {
                var range = this.get_rng(sel);
                range.pasteHTML(node.outerHTML);
            } else {
                var range = sel.getRangeAt(0);
                sel.removeAllRanges();
                range.deleteContents();
                var container = range.startContainer;
                var pos = range.startOffset;
                range = doc.createRange();
                
                if (container.nodeType == 3 && node.nodeType == 3) {
                    container.innerData(pos, node.data);
                    range.setEnd(container, pos + node.length);
                    range.setStart(container, pos + node.length);
                } else {
                    var afterNode;
                    var beforeNode;
                    if (container.nodeType == 3) {
                        var textNode = container;
                        container = textNode.parentNode;
                        var text = textNode.nodeValue;
                        
                        var textBefore = text.substr(0, pos);
                        var textAfter = text.substr(pos);
                        
                        beforeNode = document.createTextNode(textBefore);
                        afterNode = document.createTextNode(textAfter);
                        
                        container.insertBefore(afterNode, textNode);
                        container.insertBefore(node, afterNode);
                        container.insertBefore(beforeNode, node);
                        container.removeChild(textNode);
                    } else {
                        afterNode = container.childNodes[pos];
                        container.insertBefore(node, afterNode);
                    }
                    try {
                        if (afterNode) {
                            range.setEnd(afterNode, 0);
                            range.setStart(afterNode, 0);
                        }
                    } catch (e) {
                        alert(e);
                    }
                    sel.addRange(range);
                }
            }
            
        },
        get_sel: function () {
            var iframe = this.iframe;
            var doc = this.doc;
            var win = this.get_win();
            var sel = null;
            if (iframe.getSelection) sel = iframe.getSelection();
            else if (win.getSelection) sel = win.getSelection();
            else if (doc.getSelection) sel = doc.getSelection();
            else if (doc.selection) sel = doc.selection;
            return sel;
        },
        get_rng: function (sel) {
            return sel.createRange ? sel.createRange() : sel.getRangeAt(0);
        },
        get_doc: function () {
            var iframe = this.iframe;
            return iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document;
        },
        get_win: function () {
            var iframe = this.iframe;
            return iframe.contentWindow;
        },
        show_link_manager: function (x, y) {
            if ( ! this.link_manager) {
                var othis = this;
                var link_manager = document.createElement('div');
                link_manager.style.position = 'absolute';
                link_manager.className = 'box';
                link_manager.style.padding = '10px';
                link_manager.style.backgroundColor = '#fff';
                
                this.head.appendChild(link_manager);
                this.link_manager = link_manager;
                
                var input = document.createElement('input');
                input.type = 'text';
                input.className = 'text';
                link_manager.appendChild(input);
                input.value = 'http://';
                input.style.width = '300px';
                
                var insert = document.createElement('a');
                link_manager.appendChild(insert);
                insert.href = 'javascript:;';
                insert.innerHTML = 'Insert';
                insert.className = 'insert';

                insert.onclick = function () {
                    othis.exec('createlink', input.value);
                    link_manager.style.display = 'none';
                };
                
                var cancel = document.createElement('a');
                link_manager.appendChild(cancel);
                cancel.innerHTML = 'Cancel';
                cancel.className = 'cancel';
                cancel.href = 'javascript:;';
                cancel.onclick = function () {
                    link_manager.style.display = 'none';
                };
            }
            
            this.link_manager.style.left = x + 'px';
            this.link_manager.style.top =  y + 'px';
            this.link_manager.style.display = 'block';
        },
        show_image_manager: function () {
            
        },
        _setup_head: function () {
            var rts = z._rts;
            var head = this.head;
            var src = z._icons;
            var othis = this;
            
            for (var g in rts) {
                var group = document.createElement('div');
                var obj = rts[g];
                group.className = 'group';
                head.appendChild(group);
                for (var index in obj) {
                    var rt = obj[index];
                    if (rt.type == 'bt') {
                        var a = document.createElement('a');
                        group.appendChild(a);
                        
                        var cmd = rt.cmd;
                        a.href = 'javascript:;';
                        a.className = 'rt';
                        a.title = rt.label;
                        a.innerHTML = rt.label;
                        a.cmd = rt.cmd;
                        a.style.background = 'url("' + src + '") no-repeat scroll ' + rt.icon_pos + ' transparent';
                        if (rt.callback) {
                            a.callback = rt.callback;
                            a.onclick = function (e) {
                                var opts = {};
                                opts.offset_left = this.offsetLeft;
                                opts.offset_top = this.offsetTop;
                                opts.mouse_pos = z.getMousePos(e);
                                this.callback.call(othis, opts);
                            };
                        } else {
                            a.onclick = function () {
                                othis.exec(this.cmd, null);
                            };
                        }
                    } else if (rt.type == 'select') {
                        var select = rt.create_icon();
                        group.appendChild(select);
                        select.cmd = rt.cmd;
                        select.onchange = function () {
                            othis.exec(this.cmd, this.options[this.selectedIndex].value);
                        };
                    } 
                }
            }
        },
        _setup_iframe: function () {
            var iframe = this.iframe;
            var body = this.body;
            
            var elem = this.elem;
            iframe.style.width = elem.offsetWidth + 'px';
            iframe.style.height = elem.offsetHeight + 'px';
            body.style.width = elem.offsetWidth + 'px';
            body.style.height = elem.offsetHeight + 'px';
            
            iframe.style.backgroundColor = '#ffffff';
            iframe.src = 'javascript:""';
            iframe.frameborder = '0';
            iframe.border = '0';
            iframe.id = elem.id + '_ifr';
            
            iframe.contentWindow.document.designMode = "On";
            if (iframe.contentDocument)
                iframe.contentDocument.designMode = "on";
            
            var innerHTML = '';
            
            if (document.all) {
                var output = escape(this.elem.innerText);
                output = output.replace("%3CP%3E%0D%0A%3CHR%3E", "%3CHR%3E");
                output = output.replace("%3CHR%3E%0D%0A%3C/P%3E", "%3CHR%3E");
                
                innerHTML = unescape(output);
            } else {
                var htmlSrc = document.body.ownerDocument.createRange();
                htmlSrc.selectNodeContents(this.elem);
                innerHTML = htmlSrc.toString();
            }
            
            var html = '<html>' + 
                '<head>' + 
                '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' + 
                '<link rel="stylesheet" href="' + z.cdn_url('css/main.css') + '" type="text/css" />' +
                '</head>' +
                '<body class="iframe" onclick="alert(\'ggo\');">' + 
                innerHTML +
                '</body>' +
                '</html>';
            
            var doc = this.get_doc();
            doc.open();
            doc.write(html);
            doc.close();
            
            z.addEvent(doc, 'keyup', function () {alert('ggg');});
        }
    };
})();